package org.netty.message.gper.code;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.nio.ByteBuffer;

import org.netty.message.gper.entity.GpHeader;
import org.netty.message.gper.entity.GpMessageRecord;

import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.MessageToByteEncoder;

public class GpEncode extends MessageToByteEncoder<GpMessageRecord> {

	@Override
	protected void encode(ChannelHandlerContext ctx, GpMessageRecord msg, ByteBuf out) throws Exception {
		// TODO Auto-generated method stub
		ByteBuffer header = encodeHeader(msg);
		out.writeBytes(header);
		byte[] body = seriablize(msg.getBody());
		if(null!=body) {
			out.writeBytes(body);
		}
	}

	  
	private ByteBuffer encodeHeader(GpMessageRecord msg) {
		// TODO Auto-generated method stub   
		// 头部的length字段的长度
        int length = 4;

        // 对头部数据进行序列化
        byte[] headerData = seriablize(msg.getHeader());

        // 累加长度
        length += headerData.length;

        // 获取到body的长度
        int bodyLength = seriablize(msg.getBody()).length;
        // 这里类加之后，其实length就是整个报文的长度了，当然，length本身不算在里面
        length += bodyLength;
        // 所以定义一个length + headerLength +headerData 这些数据的buffer
        ByteBuffer result = ByteBuffer.allocate(4 + length  - bodyLength);

        // 设置headerLength + headerData + bodyLength的长度
        result.putInt(length);

        // 设置headerData的长度
        result.putInt(headerData.length);

        // 设置header data
        result.put(headerData);
        // 切换成读模式
        result.flip();

        return result;
        
	}

	
	private <T> byte[] seriablize(T obj) {
		// TODO Auto-generated method stub 
		try {
			ByteArrayOutputStream out = new ByteArrayOutputStream();
			ObjectOutputStream oout = new ObjectOutputStream(out);
			oout.writeObject(obj);
			return out.toByteArray();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		return null;
	}
	
}
